Skip to content

feat: 알림 구독 정보 API#90

Merged
vyfhfhd merged 5 commits into
developfrom
feature/push-subscription
Jul 27, 2026
Merged

feat: 알림 구독 정보 API#90
vyfhfhd merged 5 commits into
developfrom
feature/push-subscription

Conversation

@vyfhfhd

@vyfhfhd vyfhfhd commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

작업 내용

변경 사항

  • POST /api/v1/users/me/push-subscription 엔드포인트 추가 (UserController)
  • PushSubscriptionRequest DTO 추가 (endpoint/p256dhKey/authKey, 각각 @notblank+@SiZe)
  • UserService.registerPushSubscription() 추가
  • User.updatePushSubscription() 추가
  • UserServiceTest/UserControllerTest에 테스트 추가

리뷰 포인트

  • 이미 구독 정보가 있어도 에러 없이 최신 값으로 덮어씁니다(기기 교체/재구독 케이스로 판단). 별도 처리 필요할지 검토 부탁드려요.
  • 이 API는 구독 정보만 저장하고, 알림 on/off(pushEnabled)는 건드리지 않습니다(/me/push-setting과 관심사 분리).
  • BANNED 계정은 기존 JwtAuthenticationFilter 정책 그대로 이 API도 차단됩니다(별도 예외 처리 안 함, 논의했지만 현행 유지로 결정).

체크리스트

  • 로컬에서 실행 확인
  • Swagger 문서 갱신

Summary by CodeRabbit

  • New Features

    • Added browser push notification subscription registration for authenticated users.
    • Re-registering a subscription updates its details without changing notification settings.
    • Account withdrawal is now prevented when users have ongoing delivery parties or unsettled payouts.
    • Added clear error messages explaining withdrawal restrictions.
  • Validation

    • Added validation for push subscription details, including required fields and length limits.

@vyfhfhd vyfhfhd self-assigned this Jul 26, 2026
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@vyfhfhd, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 06acf377-b410-4e67-99d1-019c40a9d9e0

📥 Commits

Reviewing files that changed from the base of the PR and between 458a08b and 4c9c014.

📒 Files selected for processing (6)
  • src/main/java/com/leets/tdd/user/controller/UserController.java
  • src/main/java/com/leets/tdd/user/domain/User.java
  • src/main/java/com/leets/tdd/user/exception/UserErrorCode.java
  • src/main/java/com/leets/tdd/user/service/UserService.java
  • src/test/java/com/leets/tdd/user/controller/UserControllerTest.java
  • src/test/java/com/leets/tdd/user/service/UserServiceTest.java
📝 Walkthrough

Walkthrough

Changes

User account operations

Layer / File(s) Summary
Push subscription registration
src/main/java/com/leets/tdd/user/dto/PushSubscriptionRequest.java, src/main/java/com/leets/tdd/user/controller/UserController.java, src/main/java/com/leets/tdd/user/service/UserService.java, src/main/java/com/leets/tdd/user/domain/User.java, src/test/java/com/leets/tdd/user/controller/UserControllerTest.java, src/test/java/com/leets/tdd/user/service/UserServiceTest.java
Adds validated Web Push subscription registration through an authenticated endpoint, persists subscription fields, supports overwriting existing values, and preserves pushEnabled.
Withdrawal eligibility checks
src/main/java/com/leets/tdd/party/repository/*Repository.java, src/main/java/com/leets/tdd/user/service/UserService.java, src/main/java/com/leets/tdd/user/exception/UserErrorCode.java, src/test/java/com/leets/tdd/user/service/UserServiceTest.java
Adds creator and participant repository queries and blocks withdrawal for ongoing parties or completed parties with non-terminal settlement states.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant UserController
  participant UserService
  participant User
  Client->>UserController: POST /me/push-subscription with PushSubscriptionRequest
  UserController->>UserService: registerPushSubscription(userId, request)
  UserService->>User: updatePushSubscription(endpoint, keys)
  UserService-->>UserController: successful registration
  UserController-->>Client: success response
Loading

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the new push subscription information API added by this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/push-subscription

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/java/com/leets/tdd/user/service/UserService.java (1)

227-273: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider consolidating hasOngoingDeliveryParty/hasUnsettledDeliveryParty.

Both methods repeat the same "check creator → return true if found → skip if no joined parties → check joined ids" shape, differing only in which repository calls they delegate to. Extracting a shared helper reduces duplication as more withdrawal restrictions get added later.

♻️ Proposed refactor
+    private boolean existsAsCreatorOrParticipant(
+            List<Long> joinedPartyIds, BooleanSupplier creatorCheck, BooleanSupplier participantCheck) {
+        if (creatorCheck.getAsBoolean()) {
+            return true;
+        }
+        return !joinedPartyIds.isEmpty() && participantCheck.getAsBoolean();
+    }
+
     private boolean hasOngoingDeliveryParty(Long userId, List<Long> joinedPartyIds) {
-        if (deliveryPartyRepository.existsByCreatorIdAndStatusIn(userId, ONGOING_PARTY_STATUSES)) {
-            return true;
-        }
-        if (joinedPartyIds.isEmpty()) {
-            return false;
-        }
-        return deliveryPartyRepository.existsByIdInAndStatusIn(joinedPartyIds, ONGOING_PARTY_STATUSES);
+        return existsAsCreatorOrParticipant(joinedPartyIds,
+                () -> deliveryPartyRepository.existsByCreatorIdAndStatusIn(userId, ONGOING_PARTY_STATUSES),
+                () -> deliveryPartyRepository.existsByIdInAndStatusIn(joinedPartyIds, ONGOING_PARTY_STATUSES));
     }

     private boolean hasUnsettledDeliveryParty(Long userId, List<Long> joinedPartyIds) {
-        if (deliveryPartyRepository.existsByCreatorIdAndStatusAndSettlementStatusNotIn(
-                userId, PartyStatus.COMPLETED, SETTLEMENT_TERMINAL_STATUSES)) {
-            return true;
-        }
-        if (joinedPartyIds.isEmpty()) {
-            return false;
-        }
-        return deliveryPartyRepository.existsByIdInAndStatusAndSettlementStatusNotIn(
-                joinedPartyIds, PartyStatus.COMPLETED, SETTLEMENT_TERMINAL_STATUSES);
+        return existsAsCreatorOrParticipant(joinedPartyIds,
+                () -> deliveryPartyRepository.existsByCreatorIdAndStatusAndSettlementStatusNotIn(
+                        userId, PartyStatus.COMPLETED, SETTLEMENT_TERMINAL_STATUSES),
+                () -> deliveryPartyRepository.existsByIdInAndStatusAndSettlementStatusNotIn(
+                        joinedPartyIds, PartyStatus.COMPLETED, SETTLEMENT_TERMINAL_STATUSES));
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/leets/tdd/user/service/UserService.java` around lines 227 -
273, Consolidate the duplicated creator-and-participant lookup flow in
hasOngoingDeliveryParty and hasUnsettledDeliveryParty by extracting a shared
helper that accepts the relevant repository checks or predicates. Preserve the
current short-circuit behavior, including returning false when joinedPartyIds is
empty, and keep each method’s existing status and settlement criteria unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/main/java/com/leets/tdd/user/service/UserService.java`:
- Around line 227-273: Consolidate the duplicated creator-and-participant lookup
flow in hasOngoingDeliveryParty and hasUnsettledDeliveryParty by extracting a
shared helper that accepts the relevant repository checks or predicates.
Preserve the current short-circuit behavior, including returning false when
joinedPartyIds is empty, and keep each method’s existing status and settlement
criteria unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1b8a36a2-3661-4fd5-a4ee-955d8a2551bc

📥 Commits

Reviewing files that changed from the base of the PR and between 0ce2711 and 458a08b.

📒 Files selected for processing (9)
  • src/main/java/com/leets/tdd/party/repository/DeliveryPartyRepository.java
  • src/main/java/com/leets/tdd/party/repository/PartyParticipantRepository.java
  • src/main/java/com/leets/tdd/user/controller/UserController.java
  • src/main/java/com/leets/tdd/user/domain/User.java
  • src/main/java/com/leets/tdd/user/dto/PushSubscriptionRequest.java
  • src/main/java/com/leets/tdd/user/exception/UserErrorCode.java
  • src/main/java/com/leets/tdd/user/service/UserService.java
  • src/test/java/com/leets/tdd/user/controller/UserControllerTest.java
  • src/test/java/com/leets/tdd/user/service/UserServiceTest.java

@HandoA01 HandoA01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다! 웹푸시 발송 모듈에서 이 구독 정보(endpoint/키)를 꺼내 쓸 예정인데, User에 @Getter가 있어서 그대로 조회하면 될 것 같아요. 구독 정보 없는 유저(endpoint null) 발송 시도는 제 발송 모듈 쪽에서 걸러서 처리하겠습니다. 수고하셨어요!

@coderabbitai coderabbitai Bot mentioned this pull request Jul 27, 2026
2 tasks
@vyfhfhd
vyfhfhd merged commit e1f3e91 into develop Jul 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants